<?php
/**
 * Created by PhpStorm.
 * User: zhangrxiang
 * Date: 17-2-23
 * Time: 下午5:16
 */

class BaseClass {
    function __construct() {
        print "In BaseClass constructor\n";

        $args = func_get_args();
        $num = func_num_args();

        if(method_exists($this,$f = "con" . $num)){
            call_user_func_array(array($this,$f),$args);
        }else{
            foreach ($args as $k => $v){
                $this->$v = $v;
//                echo $this->$v.PHP_EOL;
//                    function () use ($v){
//                    echo $v.PHP_EOL;
//                };
            }

//            throw new Exception("No this Method ". $f);
        }
    }

    function con0(){
        echo __METHOD__.PHP_EOL;
    }
    function con2(){
        echo __METHOD__.PHP_EOL;
    }
    function con1(){
        echo __METHOD__.PHP_EOL;
    }
    function __destruct()
    {
        print __METHOD__.PHP_EOL;
    }
}

class SubClass extends BaseClass {
    function __construct() {
        parent::__construct();
        print "In SubClass constructor\n";
    }


}

class OtherSubClass extends BaseClass {

    function OtherSubClass(){
        echo __METHOD__.PHP_EOL;
        parent::__construct();
    }
}

// In BaseClass constructor
//$obj = new BaseClass();

// In BaseClass constructor
// In SubClass constructor
//$obj = new SubClass();

// In BaseClass constructor
//$obj = new OtherSubClass();
//$base = new BaseClass("con","test");
$base = new BaseClass("con","test","wocao");
echo $base->{'wocao'};



///////////////////////////////////////////////////////////////
echo PHP_EOL;
class Foo {

    /**
     * An indentifier
     * @var string
     */
    private $name;
    /**
     * A reference to another Foo object
     * @var Foo
     */
    private $link;

    public function __construct($name) {
        $this->name = $name;
    }

    public function setLink(Foo $link){
        $this->link = $link;
    }

    public function __destruct() {
        echo 'Destroying: ', $this->name, PHP_EOL;
    }
}

// create two Foo objects:
$foo = new Foo('Foo 1');
$bar = new Foo('Foo 2');
//
// make them point to each other
$foo->setLink($bar);
$bar->setLink($foo);
//
// destroy the global references to them
$foo = null;
$bar = null;

// we now have no way to access Foo 1 or Foo 2, so they OUGHT to be __destruct()ed
// but they are not, so we get a memory leak as they are still in memory.
//
// Uncomment the next line to see the difference when explicitly calling the GC:
// gc_collect_cycles();
//
// see also: http://www.php.net/manual/en/features.gc.php
//

// create two more Foo objects, but DO NOT set their internal Foo references
// so nothing except the vars $foo and $bar point to them:
$foo1 = new Foo('Foo 3');
$bar1 = new Foo('Foo 4');

gc_collect_cycles();
// destroy the global references to them
$foo1 = null;
$bar1 = null;

// we now have no way to access Foo 3 or Foo 4 and as there are no more references
// to them anywhere, their __destruct() methods are automatically called here,
// BEFORE the next line is executed:

echo 'End of script', PHP_EOL;

